﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using HslCommunication;
using Net_SCADA.Siemens;

namespace Net_SCADA
{
    public class NetLine
    {
        #region Public para
        public static string[] InterAdd { get; private set; } = null;
        public static string[] DBIndex { get; private set; } = null;
        public static int iSaveInterval { get; set; } = 30;//数据保存间隔
        public static Dictionary<string, NetEquip> Equip { get; set; } = new Dictionary<string, NetEquip>();
        public static Dictionary<int, ProcessLoad> LineProcessLoad { get; set; } = new Dictionary<int, ProcessLoad>();
        public static List<Zone> zone { get; set; } = new List<Zone>();
        public static List<Alarm> alarm { get; set; } = new List<Alarm>();
        public static  List<Alarm> status { get; } = new List<Alarm>();
        public static List<SetPoint> setpoint { get; set; } = new List<SetPoint>();
        public static List<SetPoint> othersetpoint { get; set; } = new List<SetPoint>();
        public static List<ProcessBox> pBox { get; set; } = new List<ProcessBox>();
        public static List<KeyPostion> keyPos { get; set; } = new List<KeyPostion>();
        public static List<KeyTime> BoxKeyTime { get; private set; } = new List<KeyTime>();
        public static bool isNeedFlashAlarm { get; set; } = false;
        public static Dictionary<int, Color[]> AlarmLevelColor { get; set; } = new Dictionary<int, Color[]>();
        public static List<ProcessBatch> Batchs { get; set; } = new List<ProcessBatch>();
        public static bool isBatchStart { get; set; } = false;
        public static hsl_Server hslServer { get; set; }
        public static hsl_Client hsl_Alarm { get; private set; }
        public static hsl_Client hsl_Status { get; private set; }
        public static hsl_Client hsl_PV { get; private  set; }
        public static hsl_Client hsl_SV { get; private set; }
        public static hsl_Client hsl_OVPV { get; private set; }
        public  static hsl_Client hsl_OVSV { get; private set; }
        public static hsl_Client hsl_Bais { get;private set; }
        public static hsl_Client hsl_Diff { get; private  set; }
        public static hsl_Client hsl_SetPoint { get; private set; }
        public static hsl_Client hsl_MarkAndBoxserial { get; set; }
        private static hsl_Client hsl_AlarmForPLC { get; set; }
        public static hsl_Client hsl_OtherSetpoint { get; set; }
        public static int DesignCols { get; set; } = 10;
        public static byte[] cutedProcessBoxInfo { get; set; } = null;
        #endregion

        #region private par
        private static int[] ALarmForPLC = new int[3];
        private static StringBuilder[] LastLevelAlarm = new StringBuilder[3] { new StringBuilder(), new StringBuilder(), new StringBuilder() };
        private static List<int> AllProcessLoadList = new List<int>();
        private static DataTable dtZoneSet = new DataTable();
        private static DataTable dtItemSet = new DataTable();
        private static DateTime lastSaveTime = DateTime.Now;
        private static bool isNeedCheckLoadForEnd = false;
        private static string hslPLCIP = "127.0.0.1";
        private static bool isLoading =true;
        #endregion
        public static void LoadSetting()
        {
            LoadHSLServerSetting();
            LoadEquipSetting();
            LoadZoneSetting();
            LoadProcessBox();
            LoadAlarmSetting();
            LoadStatusSetting();
            LoadAlarmLevelColor();
            LoadBatchSerial();
            LoadKeyTimeSet();
            MultipleLanguage.loadMessageInfos();    
            SetHSLAdd();
            isLoading = false;
        }

        public static void GetDataFromPLC()
        {
            if (isLoading) return;
            FillZonePV();
            FillZoneSV();
            FillZoneOVPV();
            FillProessBox();
            FillAlarm();
            FillStatus();
            SendDataToPLC();
            SaveDataToDataBase();
        }

        #region loadsettings

        private static void LoadAlarmLevelColor()
        {
            DataTable dt=DBOperate.GetAlarmLevelColorSet();
            if (dt == null || dt.Rows.Count == 0) return;
            Color[] color=new Color[2];
            for (int i = 0 ; i < dt.Rows.Count ; i++)
            {
                try
                {
                    int index=Convert.ToInt32(dt.Rows[i]["allevel"].ToString());
                    AlarmLevelColor.Add(index , new Color[2]);
                    color[1] = Color.FromArgb( Convert.ToInt32(dt.Rows[i]["albackcolor"]));
                    color[0] = Color.FromArgb(Convert.ToInt32(dt.Rows[i]["alforecolor"]));
                    AlarmLevelColor[index][0] = color[0];
                    AlarmLevelColor[index][1] = color[1];

                }
                catch (Exception)
                {
                    continue;
                }
            }
        }
        private static void LoadBatchSerial()
        {
            DataTable dtbatch=DBOperate.GetBatchs();
            if (dtbatch == null || dtbatch.Rows.Count == 0) return;
            for (int i = 0 ; i < dtbatch.Rows.Count ; i++)
            {
                Batchs.Add(new ProcessBatch()
                {
                    BatchSerial = new StringBuilder(dtbatch.Rows[i]["batchserial"].ToString()) ,
                    CreateTime = Convert.ToDateTime(dtbatch.Rows[i]["createtime"]) ,
                    isBatchRunning = dtbatch.Rows[i]["isbatchrunning"].ToString() == "1" ? true : false,
                    CreateUser= dtbatch.Rows[i]["createuser"].ToString(),
                    ProductVersion= dtbatch.Rows[i]["productversion"].ToString() 
                });
                ProcessBatch batch=Batchs.Last();
               // batch.SetProductAlarmSettting();
                if (DateTime.TryParse(dtbatch.Rows[i]["endtime"].ToString() , out DateTime v))
                    batch.EndTime = v;
                if (DateTime.TryParse(dtbatch.Rows[i]["stoptime"].ToString() , out v))
                {
                    batch.StopTime = v;
                    batch.isBatchStop = true;
                }
                DataTable dtload=DBOperate. GetProcessBoxByBatchserial(batch.BatchSerial.ToString());
                if (dtload == null || dtload.Rows.Count == 0) continue;
                for (int j = 0 ; j < dtload.Rows.Count ; j++)
                {
                    int mark=Convert.ToInt32( dtload.Rows[j]["mark"].ToString());
                    int serial=Convert.ToInt32(dtload.Rows[j]["box"].ToString());
                    batch.DictProcessLoad.Add(serial * 10000 + mark , new ProcessLoad()
                    {
                        BatchSerial = batch.BatchSerial ,
                        BoxMark =mark ,
                        BoxSerial =serial ,
                    });
                    if (DateTime.TryParse(dtload.Rows[j]["loadtime"].ToString() , out v))
                    {
                        batch.DictProcessLoad[serial * 10000 + mark].LoadTime = v;
                    }
                }
            }
            if (!Batchs.Last().isBatchStop) isBatchStart = true;
           // FillProessBox();
            NetLine_OnBoxSerialChanged(null);
        }
        public static void LoadEquipSetting()
        {
            DataTable dt=DBOperate.GetEquipSet();
            if (dt == null || dt.Rows.Count == 0) return;
            foreach (DataRow rw in dt.Rows)
            {
                Equip.Add(rw["equipid"].ToString() ,new NetEquip() { 
                    EquipName=rw["equipname"].ToString().Split(';'),
                    EquipID= rw["equipid"].ToString(),
                    PassTime =Convert.ToSingle(rw["equipPassTime"])
                });
            }
            string _filename = Application.StartupPath + "\\Settings\\DataSetting.dat";
            if (File.Exists(_filename))
            {
                Ini inf = new Ini(_filename);
                DBIndex=inf.ReadValue("Box","DBIndex").Split(new char[]{ '|'});
                InterAdd= inf.ReadValue("Box" , "BoxAdd").Split(new char[] { '|' });
                string[] pos= inf.ReadValue("Box" , "KeyPos").Split(new char[] { '|' });
                int k;
                for (int i = 0 ; i < pos.Length ; i++)
                {
                    if(int.TryParse(pos[i] , out k) && k>0)
                    {
                        keyPos.Add(new KeyPostion(k));
                    }
                }
            }
        }
        private static void LoadKeyTimeSet()
        {
            DataTable dt =DBOperate.GetKeyTimeSet();
            if (dt == null || dt.Rows.Count == 0) return;
            for (int i = 0 ; i < dt.Rows.Count ; i++)
            {
                BoxKeyTime.Add(new KeyTime()
                {
                    KeyTimeName = dt.Rows[i]["keytimename"].ToString().Split(';') ,
                    KeyTimeInIndex = Convert.ToInt32(dt.Rows[i]["keytimeinindex"]) ,
                    KeyTimeOutIndex = Convert.ToInt32(dt.Rows[i]["keytimeoutindex"])
                });
                BoxKeyTime.Last().SetZoneID(dt.Rows[i]["zoneid"].ToString());
            }
        }
        private static void LoadHSLServerSetting()
        {
            string _filename = Application.StartupPath + "\\Settings\\setting.dat";
            if (!File.Exists(_filename)) return;
            Ini setting=new Ini(_filename);
            hslPLCIP = setting.ReadValue("PLC" , "PLCIP");
            hslServer = new hsl_Server(hslPLCIP);
            hslServer.ConnectToPLC();

            DesignCols = Convert.ToInt32("0" + setting.ReadValue("Interface", "DesignCols"));
            if (DesignCols == 0) DesignCols = 10;
        }
        private static void LoadProcessBox()
        {
            if (DBIndex == null) return;
            hsl_MarkAndBoxserial = new hsl_Client(hslServer);
            List<string> lstforMarkAndBoxserial = new List<string>();
            string[] add = new string[3];
            for (int i = 0; i < DBIndex.Length; i++)
            {
                pBox.Add(new ProcessBox(i, DBIndex[i]));
                pBox[i].initHSLClient(hslServer, InterAdd);
                pBox[i].OnBoxSerialChanged += NetLine_OnBoxSerialChanged;
                lstforMarkAndBoxserial.AddRange(new string[3] { DBIndex[i] + "," + InterAdd[0], DBIndex[i] + "," + InterAdd[1], DBIndex[i] + "," + InterAdd[2] });
            }
            hsl_MarkAndBoxserial.InstallHslItems(lstforMarkAndBoxserial);
            for (int i = 0; i < keyPos.Count; i++)
            {
                if (keyPos[i].PostionIndex <= pBox.Count)
                {
                    pBox[keyPos[i].PostionIndex - 1].isKeyPostion = true;
                    keyPos[i].processBox = pBox[keyPos[i].PostionIndex - 1];
                }
            }
        }
        private static void LoadAlarmSetting()
        {
            DataTable dtAlarmSet = DBOperate.GetAlarmSet();
            if (dtAlarmSet == null || dtAlarmSet.Rows.Count == 0) return;
            hsl_Alarm = new hsl_Client(hslServer);
            hsl_AlarmForPLC = new hsl_Client(hslServer);
            List<string> lst = new List<string>();
            for (int i = 0; i < dtAlarmSet.Rows.Count; i++)
            {
                alarm.Add(new Alarm()
                {
                    AlarmName = dtAlarmSet.Rows[i]["alName"].ToString().Split(';'),
                    AlarmID = Convert.ToInt32(dtAlarmSet.Rows[i]["alID"].ToString()),
                    AlarmLevel = Convert.ToInt32(dtAlarmSet.Rows[i]["allevel"].ToString()),
                    AlarmTypeID = Convert.ToInt32(dtAlarmSet.Rows[i]["altypeid"].ToString()),
                    AlarmEquipID = dtAlarmSet.Rows[i]["equipid"].ToString(),
                    AlarmAdd = dtAlarmSet.Rows[i]["alAdd"].ToString(),
                    AlarmAction = Convert.ToInt32(dtAlarmSet.Rows[i]["alAction"].ToString()),
                });
                alarm.Last().SetAlarmPostion(dtAlarmSet.Rows[i]["postionid"].ToString());
                Equip[alarm.Last().AlarmEquipID].EquipAlarm.Add(alarm.Last());
                lst.Add(alarm.Last().AlarmAdd);
            }
            hsl_Alarm.InstallHslItems(lst);
            hsl_AlarmForPLC.InstallHslItems(new List<string>() { "MX91.0", "MX91.1", "MX91.2", "MX90.0", "MX90.1", "MX90.2" });
        }
        private static void LoadZoneSetting()
        {
            dtZoneSet = DBOperate.GetZoneSet();
            dtItemSet = DBOperate.GetItemSet();
            List<string> lstsv = new List<string>();
            List<string> lstothersv = new List<string>();

            if (dtZoneSet == null || dtItemSet == null || dtItemSet.Rows.Count == 0 || dtZoneSet.Rows.Count == 0) return;
            hsl_OtherSetpoint = new hsl_Client(hslServer);
            hsl_SetPoint = new hsl_Client(hslServer);

            for (int i = 0; i < dtZoneSet.Rows.Count; i++)
            {
                Zone z = new Zone()
                {
                    pv = SetZoneItem(i, "pvid"),
                    sv = SetZoneItem(i, "svid"),
                    ovpv = SetZoneItem(i, "ovpvid"),
                    ovsv = SetZoneItem(i, "ovsvid"),
                    ubais = SetZoneItem(i, "ubaisID"),
                    lbais = SetZoneItem(i, "lbaisID"),
                    diff = SetZoneItem(i, "diffid"),
                    ZoneName = dtZoneSet.Rows[i]["zoneName"].ToString().Split(';'),
                    Unit = dtZoneSet.Rows[i]["unit"].ToString(),
                    ID = Convert.ToInt32(dtZoneSet.Rows[i]["zoneID"].ToString()),
                    GroupID = Convert.ToInt32(dtZoneSet.Rows[i]["GroupID"].ToString()),
                    EquipID = dtZoneSet.Rows[i]["EquipID"].ToString(),
                    isSV = Convert.ToInt32(dtZoneSet.Rows[i]["issv"].ToString()) == 1 ? true : false,
                    svtype = Convert.ToInt32(dtZoneSet.Rows[i]["svtype"].ToString()),
                };
                if (dtZoneSet.Columns.Contains("bindAlarmID")) z.BindingAlarm(dtZoneSet.Rows[i]["bindAlarmID"].ToString());
                zone.Add(z);
                Equip[z.EquipID].EquipZone.Add(zone.Last());
                if (z.isSV)
                {
                    Item sv = z.sv;
                    if (sv == null) continue;
                    SetPoint sp = new SetPoint()
                    {
                        GroupID = z.GroupID,
                        ZoneID = z.ID,
                        ZoneName = z.ZoneName,
                        Unit = z.Unit,
                        ItemID = z.ID,
                        sv = new Item()
                        {
                            ID = sv.ID,
                            Add = sv.Add,
                            DataType = sv.DataType,
                            DP = sv.DP,
                            Min = sv.Min,
                            Max = sv.Max
                        }
                    };
                    sp.sv.ID = sp.ItemID;
                    string[] v = getAddByItem(sp.sv);
                    if (z.svtype < 10)
                    {
                        setpoint.Add(sp);
                        if (v != null) lstsv.AddRange(v);
                    }
                    else
                    {
                        othersetpoint.Add(sp);
                        if (v != null) lstothersv.AddRange(v);
                    }
                }
            }
            hsl_SetPoint.InstallHslItems(lstsv);
            hsl_OtherSetpoint.InstallHslItems(lstothersv);
        }
        private static void LoadStatusSetting()
        {
            List<string> lst = new List<string>();
            hsl_Status = new hsl_Client(hslServer);
            DataTable dtStatusSet = DBOperate.GetStatusSet();
            if (dtStatusSet == null || dtStatusSet.Rows.Count == 0) return;
            for (int i = 0; i < dtStatusSet.Rows.Count; i++)
            {
                Alarm al = new Alarm()
                {
                    AlarmName = dtStatusSet.Rows[i]["alName"].ToString().Split(';'),
                    AlarmID = Convert.ToInt32(dtStatusSet.Rows[i]["alID"].ToString()),
                    AlarmEquipID = dtStatusSet.Rows[i]["Equipid"].ToString(),
                    AlarmAdd = dtStatusSet.Rows[i]["alAdd"].ToString()
                };
                status.Add(al);
                lst.Add(al.AlarmAdd);
            }
            hsl_Status.InstallHslItems(lst);
        }
        private static string[] getAddByItem(Item item)
        {
            if (item == null) return null;
            if (item.DataType.ToUpper() == "TIME")
                return item.Add.Split(new char[] { '|' });
            return new string[] { item.Add };
        }
        private static Item SetZoneItem(int zoneindex, string itemid)
        {
            int id;
            int.TryParse(dtZoneSet.Rows[zoneindex][itemid].ToString(), out id);
            if (id > 0)
            {
                DataRow[] row = dtItemSet.Select("itemID=" + id);
                if (row.Length > 0)
                {
                    return new Item()
                    {
                        ID = Convert.ToInt32(row[0]["itemID"].ToString()),
                        Add = row[0]["itemAdd"].ToString(),
                        DataType = row[0]["Type"].ToString(),
                        DP = Convert.ToInt32(row[0]["DP"].ToString()),
                        Min = Convert.ToSingle(row[0]["smin"].ToString()),
                        Max = Convert.ToSingle(row[0]["smax"].ToString()),
                        isRecord = row[0]["isRecord"].ToString() == "1" ? true : false,
                        isShow = row[0]["isShow"].ToString() == "1" ? true : false
                    };
                }
            }
            return null;
        }
        private static void SetHSLAdd()//给各个HSLCLIENT添加数据
        {
            hsl_PV = new hsl_Client(hslServer);
            List<string> lstpv = new List<string>();
            hsl_SV = new hsl_Client(hslServer);
            List<string> lstsv = new List<string>();
            hsl_OVPV = new hsl_Client(hslServer);
            List<string> lstovpv = new List<string>();
            hsl_OVSV = new hsl_Client(hslServer);
            List<string> lstovsv = new List<string>();
            hsl_Bais = new hsl_Client(hslServer);
            List<string> lstbais = new List<string>();
            hsl_Diff = new hsl_Client(hslServer);
            List<string> lstdiff = new List<string>();
            string[] v;
            for (int i = 0; i < zone.Count; i++)
            {
                v = getAddByItem(zone[i].pv);
                if (v != null) lstpv.AddRange(v);
                v = getAddByItem(zone[i].sv);
                if (v != null) lstsv.AddRange(v);
                v = getAddByItem(zone[i].ovpv);
                if (v != null) lstovpv.AddRange(v);
                v = getAddByItem(zone[i].ovsv);
                if (v != null) lstovsv.AddRange(v);
                v = getAddByItem(zone[i].ubais);
                if (v != null) lstbais.AddRange(v);
                v = getAddByItem(zone[i].lbais);
                if (v != null) lstbais.AddRange(v);
                v = getAddByItem(zone[i].diff);
                if (v != null) lstdiff.AddRange(v);
            }
            hsl_PV.InstallHslItems(lstpv);
            hsl_SV.InstallHslItems(lstsv);
            hsl_OVPV.InstallHslItems(lstovpv);
            hsl_OVSV.InstallHslItems(lstovsv);
            hsl_Bais.InstallHslItems(lstbais);
            hsl_Diff.InstallHslItems(lstdiff);
        }
        #endregion

        #region send2PLC
        public static async void SendDataToPLC()
        {
            if (hsl_Bais.IsNeedSetValue) hsl_Bais.SetItemValues(hsl_Bais.SetValues);
            if (hsl_Diff.IsNeedSetValue) hsl_Diff.SetItemValues(hsl_Diff.SetValues);
            if (hsl_OVSV.IsNeedSetValue) hsl_OVSV.SetItemValues(hsl_OVSV.SetValues);
            if (hsl_OtherSetpoint.IsNeedSetValue) hsl_OtherSetpoint.SetItemValues(hsl_OtherSetpoint.SetValues);
            if (hsl_SetPoint.IsNeedSetValue) hsl_SetPoint.SetItemValues(hsl_SetPoint.SetValues);
            //时间同步写入到PLC
            OperateResult res= hslServer.SiemensPLC.Write("DB49.0", DateTime.Now);
            if (res.IsSuccess)
            {
                hslServer.SiemensPLC.Write("M407.2", true);
                await Task.Delay(100);
                hslServer.SiemensPLC.Write("M407.2", false);
                await Task.Delay(100);
            }

        }
        private static async void SendLevelAlarm(int levelindex, bool v)
        {
            if (v)
            {
                hsl_AlarmForPLC.RandemSetItemValues(new Dictionary<int, object>() { { levelindex, v } });
                await Task.Delay(200);
            }
            hsl_AlarmForPLC.RandemSetItemValues(new Dictionary<int, object>() { { levelindex, 0 }, { levelindex + 3, v } });
            await Task.Delay(200);
        }
        #endregion

        #region Box changed
        private static void NetLine_OnBoxSerialChanged(ProcessBox processBox)
        {
            if (!(processBox==null || LineProcessLoad.ContainsKey(processBox.LoadSerial)))
            {
                if(processBox.BoxSerial* processBox.BoxMark != 0)
                {
                    LineProcessLoad.Add(processBox.LoadSerial , new ProcessLoad()
                    {
                        BoxSerial = processBox.BoxSerial ,
                        BoxMark = processBox.BoxMark ,
                        LoadTime = processBox.LoadTime,
                    });
                    if (Batchs.Count > 0)
                    {
                        if (
                            !Batchs.Last().isBatchStop 
                            && !Batchs.Last().DictProcessLoad.ContainsKey(processBox.LoadSerial)
                            && LineProcessLoad[processBox.LoadSerial].LoadTime < Batchs.Last().CreateTime
                         )
                        {
                            Batchs.Last().DictProcessLoad.Add(processBox.LoadSerial , LineProcessLoad[processBox.LoadSerial]);
                            Batchs.Last().DictProcessLoad[processBox.LoadSerial].BatchSerial = Batchs.Last().BatchSerial;
                           // Batchs.Last().DictProcessLoad[processBox.LoadSerial].SaveProcessLoadToDB();
                        }
                    }
                }
            }
            if(processBox!=null && processBox.BoxSerial * processBox.BoxMark != 0)
               // if (processBox!=null && processBox.isKeyPostion && processBox.BoxSerial * processBox.BoxMark != 0)
            {
                processBox.SaveBoxInfo();
            }
            isNeedCheckLoadForEnd = true;
        }
        private static void CheckLoadForEnd()
        {
            if (AllProcessLoadList.Count != pBox.Count) return;
            List<ProcessBatch> v=new List<ProcessBatch>();
            if (Batchs.Count > 0)
            {
                for (int i = 0 ; i < Batchs.Count ; i++)
                {
                    Batchs[i].CheckAndEndProcessLoad(AllProcessLoadList);
                    if ((Batchs[i].isBatchStop) && (Batchs[i].DictProcessLoad.Count == 0))
                    {
                        Batchs[i].EndProcessBatch();
                        v.Add(Batchs[i]);
                    }
                }
                foreach (var item in v)
                {
                    Batchs.Remove(item);
                }
            }
            isNeedCheckLoadForEnd = false;
        }
        private static void CheckProductAlarm(Alarm al)
        {
            if(al.AlarmPostion.Count>0)//如果有标记物料位置
            {
                for (int i = 0 ; i < al.AlarmPostion.Count ; i++)//对每个位置的物料进行标记
                {
                    if (al.AlarmPostion[i]>0 && pBox[al.AlarmPostion[i]-1].LoadIndex > 0)//如果对应位置有物料
                    {
                        Dictionary<int,object> plcvalue=new Dictionary<int, object>();
                        if (pBox[al.AlarmPostion[i]-1].LampCode != 1)
                        {
                            plcvalue.Add(7 , 1);
                            pBox[al.AlarmPostion[i] - 1].LampCode = 1;
                        }
                        if (al.AlarmAction == 2 && pBox[al.AlarmPostion[i] - 1].ErrorCode != 1)
                        {
                            plcvalue.Add(4 , 1);
                            pBox[al.AlarmPostion[i] - 1].ErrorCode = 1;
                        }
                        if(plcvalue.Count>0) pBox[al.AlarmPostion[i]-1].SetAlarmStatusToPLC(plcvalue);//给PLC异常信息
                    }
                }
            }
        }
        #endregion

        #region Data Fill
        private static void FillStatus()
        {
            hsl_Status.GetDataFromPLC();
            if (hsl_Status.ItemValues.Count != hsl_Status.hslitems.Count) return;
            List<object> v = hsl_Status.ItemValues;
            for (int i = 0; i < status.Count; i++)
            {
                status[i].AlarmValue = Convert.ToBoolean(v[i]);
            }
        }
        private static void FillAlarm()
        {//`SaveTime`,`AlarmName`,`AlarmActive`,`AlarmLevel`,`AlarmID`
            hsl_Alarm.GetDataFromPLC();
            if (hsl_Alarm.ItemValues.Count != hsl_Alarm.hslitems.Count) return;
            List<string[]> DetailForSave=new List<string[]>();
            StringBuilder[] NewLevelAlarm=new StringBuilder[3] { new StringBuilder(), new StringBuilder(), new StringBuilder() };
            List<object> v = hsl_Alarm.ItemValues;
            Array.Clear(ALarmForPLC , 0 , ALarmForPLC.Length);
            for (int i = 0 ; i < alarm.Count ; i++)
            {
                alarm[i].AlarmValue = Convert.ToBoolean(v[i]);
                if (alarm[i].AlarmValue && alarm[i].AlarmAction>0)
                    CheckProductAlarm(alarm[i]);
                if (alarm[i].IsChanged)
                {
                    DetailForSave.Add(new string[5] {
                        DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        alarm[i].AlarmName[0],
                        alarm[i].AlarmValue?"1":"0",
                        alarm[i].AlarmLevel.ToString(),
                        alarm[i].AlarmID.ToString()
                    });
                }
                try
                {
                    NewLevelAlarm[alarm[i].AlarmLevel - 1].Append(alarm[i].AlarmValue?'1':'0');
                    ALarmForPLC[alarm[i].AlarmLevel - 1] += alarm[i].AlarmValue ? 1 : 0;
                }
                catch (Exception)
                {
                    continue;
                }
            }
            if (DetailForSave.Count > 0)//有新的报警变化
            {
                //DBOperate.SaveAlarmData(DetailForSave);
                DBOperate.SaveAlarmDataByDay(DetailForSave);
                SaveAlarmToFile(DetailForSave);
                isNeedFlashAlarm = true;
            }
            if (isNeedFlashAlarm)
            {
                if (netForms.Formindex == 3)
                    netForms.fmAlarm.FlashAlarm();
                isNeedFlashAlarm = false;
            }
            for (int i = 0 ; i < NewLevelAlarm.Length ; i++)
            {
                if (LastLevelAlarm[i].ToString()!= NewLevelAlarm[i].ToString())
                {
                    LastLevelAlarm[i] = new StringBuilder().Append(NewLevelAlarm[i]);
                    SendLevelAlarm(i, ALarmForPLC[i] > 0);
                }
            }
            foreach (string item in Equip.Keys)
            {
                Equip[item].OnAlarm = false;
                for (int i = 0 ; i < Equip[item].EquipAlarm.Count; i++)
                {
                    if (Equip[item].EquipAlarm[i].AlarmValue)
                    {
                        Equip[item].OnAlarm = true;
                        break;
                    }
                }
            }
        }
        private static  void SaveAlarmToFile(List<string[]> v)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < v.Count; i++)
            {
                for (int j = 0; j < v[i].Length; j++)
                {
                    sb.Append(v[i][j]+",");
                }
                sb.Append("\n");
            }
            using (StreamWriter sw = new StreamWriter(CreateAlarmFilename(), true, Encoding.GetEncoding(936)))
            {
                sw.WriteLine(sb.Remove(sb.Length-1,1));
            }
        }
        private static  string CreateAlarmFilename()
        {
            DateTime date = DateTime.Now.Date;

            StringBuilder _fullfilename = new StringBuilder(Application.StartupPath).Append("\\RecordData\\").Append(date.Year).Append("\\").Append(date.ToString("MM")) .Append("\\alarm\\");
            if (!Directory.Exists(_fullfilename.ToString())) { Directory.CreateDirectory(_fullfilename.ToString()); }
            _fullfilename.Append(DateTime.Now.ToString("yyyy-MM-dd")).Append(".alm.csv");
            if (!File.Exists(_fullfilename.ToString()))
            {
                //创建文件
                //添加文件数据的标题
                StringBuilder sb = new StringBuilder("时间,警报名称,警报动作,警报等级,警报编号");
                if (sb.Length > 0)
                {
                    using (StreamWriter sw = new StreamWriter(_fullfilename.ToString(), true, Encoding.GetEncoding(936)))
                    {
                        sw.WriteLine(sb);
                    }
                }
            }
            return _fullfilename.ToString();
        }
        private static void FillProessBox()
        {
            hsl_MarkAndBoxserial.GetDataFromPLC();
            AllProcessLoadList.Clear();
            List<object> v = hsl_MarkAndBoxserial.ItemValues;
            for (int i = 0; i < v.Count; i += 3)
            {
                pBox[i / 3].LoadIndex = Convert.ToInt32(v[i]);
                pBox[i / 3].BoxMark = Convert.ToInt32(v[i + 1]);
                pBox[i / 3].BoxSerial = Convert.ToInt32(v[i + 2]);
                //if(pBox[i / 3].BoxSerial* pBox[i / 3].BoxMark>0)
                AllProcessLoadList.Add(pBox[i / 3].BoxSerial * 10000 + pBox[i / 3].BoxMark);
            }
            if (isNeedCheckLoadForEnd) CheckLoadForEnd();
        }
        private static void FillZonePV()
        {
            hsl_PV.GetDataFromPLC();
            if (hsl_PV.ItemValues.Count != hsl_PV.hslitems.Count) return;

            int _index =0;
            List<object> v = hsl_PV.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].pv;
                if (item != null && item.Add.Length!=0 && _index<v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        private static void FillZoneSV()
        {
            hsl_SV.GetDataFromPLC();
            if (hsl_SV.ItemValues.Count != hsl_SV.hslitems.Count) return;

            int _index =0;
            List<object> v = hsl_SV.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].sv;
                if (item != null && item.Add.Length!=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        public  static void FillSetPoint()
        {
            hsl_SetPoint.GetDataFromPLC();
            if (hsl_SetPoint.ItemValues.Count != hsl_SetPoint.hslitems.Count) return;

            int _index =0;
            List<object> v = hsl_SetPoint.ItemValues;
            for (int i = 0 ; i < setpoint.Count ; i++)
            {
                Item item=setpoint[i].sv;
                if (item != null && item.Add.Length!=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        public static void FillOtherSetPoint()
        {
            hsl_OtherSetpoint.GetDataFromPLC();
            if (hsl_OtherSetpoint.ItemValues.Count != hsl_OtherSetpoint.hslitems.Count) return;
            int _index=0;
            List<object> v = hsl_OtherSetpoint.ItemValues;
            for (int i = 0 ; i < othersetpoint.Count ; i++)
            {
                Item item=othersetpoint[i].sv;
                if (item != null && item.Add.Length != 0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        private static void FillZoneOVPV()
        {
            hsl_OVPV.GetDataFromPLC();
            if (hsl_OVPV.ItemValues.Count != hsl_OVPV.hslitems.Count) return;
            int _index=0;
            List<object> v = hsl_OVPV.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].ovpv;
                if (item != null && item.Add.Length!=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        public static void FillZoneOVSV()
        {
            hsl_OVSV.GetDataFromPLC();
            if (hsl_OVSV.ItemValues.Count != hsl_OVSV.hslitems.Count) return;
            int _index=0;
            List<object> v = hsl_OVSV.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].ovsv;
                if (item != null && item.Add.Length!=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        public static void FillZoneBais()
        {
            hsl_Bais.GetDataFromPLC();
            if (hsl_Bais.ItemValues.Count != hsl_Bais.hslitems.Count) return;
            int _index=0;
            List<object> v = hsl_Bais.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].ubais;
                if (item != null && item.Add.Length!=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
                item=zone[i].lbais;
                if (item != null && item.Add != "" && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        public static void FillZoneDiff()
        {
            hsl_Diff.GetDataFromPLC();
            if (hsl_Diff.ItemValues.Count != hsl_Diff.hslitems.Count) return;
            int _index=0;
            List<object> v = hsl_Diff.ItemValues;
            for (int i = 0 ; i < zone.Count ; i++)
            {
                Item item=zone[i].diff;
                if (item != null && item.Add.Length !=0 && _index < v.Count)
                {
                    if (item.DataType.ToUpper() == "TIME")
                        item.SetItemValue(new object[] { v[_index++] , v[_index++] });
                    else
                        item.SetItemValue(new object[] { v[_index++] });
                }
            }
        }
        private static void SaveDataToDataBase()
        {
            if (DateTime.Now.Subtract(lastSaveTime).TotalSeconds >= iSaveInterval)
            {
                //Console.WriteLine(lastSaveTime);
                lastSaveTime = lastSaveTime.AddSeconds(iSaveInterval);
                //savedata
                Task t = new Task(() =>
                {
                    Dictionary<int,double> values=new Dictionary<int, double>();
                    List<double> v = new List<double>();
                    for (int i = 0; i < zone.Count; i++)
                    {
                        if (zone[i].pv != null)
                        {
                            values.Add(zone[i].pv.ID, zone[i].pv.ItemValue);
                            v.Add(zone[i].pv.ItemValue);
                        }
                        if (zone[i].sv != null)
                        {
                            values.Add(zone[i].sv.ID, zone[i].sv.ItemValue);
                            v.Add(zone[i].sv.ItemValue);
                        }
                        if (zone[i].ovpv != null)
                        {
                            values.Add(zone[i].ovpv.ID, zone[i].ovpv.ItemValue);
                            v.Add(zone[i].ovpv.ItemValue);
                        }
                    }
                    //DBOperate.SaveParameterData(values);
                    DBOperate.SaveParameterDataByDay(values);
                    SaveDataToFile(v);
                });
                t.Start();
            }
        }
        private static void SaveDataToFile(List<double> v)
        {
            StringBuilder sb = new StringBuilder(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")).Append(",");
            for (int i = 0; i < v.Count; i++)
            {
                sb.Append(v[i]).Append(",");
            }
            using (StreamWriter sw = new StreamWriter(CreateDayFilename(), true, Encoding.GetEncoding(936)))
            {
                sw.WriteLine(sb);
            }
        }
        private static string CreateDayFilename()
        {
            DateTime date = DateTime.Now.Date;

            StringBuilder _fullfilename = new StringBuilder(Application.StartupPath).Append("\\RecordData\\").Append(date.Year).Append("\\").Append(date.ToString("MM")).Append("\\day\\");
            if (!Directory.Exists(_fullfilename.ToString())) { Directory.CreateDirectory(_fullfilename.ToString()); }
            _fullfilename.Append(DateTime.Now.ToString("yyyy-MM-dd")).Append(".day.csv");
            if (!File.Exists(_fullfilename.ToString()))
            {
                //创建文件
                //添加文件数据的标题
                StringBuilder sb = new StringBuilder("时间,");
                for (int i = 0; i < zone.Count; i++)
                {
                    if (zone[i].pv != null)
                        sb.Append(zone[i].ZoneName).Append("(PV)").Append(",");
                    if (zone[i].sv != null)
                        sb.Append(zone[i].ZoneName).Append("(SV)").Append(",");
                    if (zone[i].ovpv != null)
                        sb.Append(zone[i].ZoneName).Append("(OVPV)").Append(",");
                }
                if (sb.Length > 0)
                {
                    using (StreamWriter sw = new StreamWriter(_fullfilename.ToString(), true, Encoding.GetEncoding(936)))
                    {
                        sw.WriteLine(sb);
                    }
                }
            }
            return _fullfilename.ToString();
        }
        #endregion
    }
}
